
/*-------------------------------------------------------------------------
 *
 * 伪随机数生成器
 *
 * Copyright (c) 2021-2022, PostgreSQL Global Development Group
 *
 * src/include/common/pg_prng.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_PRNG_H
#define PG_PRNG_H

/*
 * PRNG 生成的状态向量。调用者应将其视为不透明的 typedef，
 * 但我们暴露其定义以便将其嵌入其他结构中。
 */
typedef struct pg_prng_state
{
	uint64		s0,
				s1;
} pg_prng_state;

/*
 * 不需要本地 PRNG 系列的调用者可以在用 pg_prng_...seed 函数初始化后，
 * 使用这个全局状态向量。
 */
extern PGDLLIMPORT pg_prng_state pg_global_prng_state;

extern void pg_prng_seed(pg_prng_state *state, uint64 seed);
extern void pg_prng_fseed(pg_prng_state *state, double fseed);
extern bool pg_prng_seed_check(pg_prng_state *state);

/*
 * 从 pg_strong_random 源初始化 PRNG 状态，
 * 确保我们不生成全零。如果返回 false，
 * 调用者应从其他随机种子初始化 PRNG 状态，
 * 使用 pg_prng_[f]seed。
 *
 * 我们将其实现为宏，以便 pg_strong_random() 调用在调用者中。
 * 如果在 pg_prng.c 中，那么使用 pg_prng.c 的程序
 * 但不需要强种子的，仍然会被迫引入 pg_strong_random.c 和 OpenSSL。
 */
#define pg_prng_strong_seed(state) \
	(pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \
	 pg_prng_seed_check(state) : false)

extern uint64 pg_prng_uint64(pg_prng_state *state);
extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax);
extern int64 pg_prng_int64(pg_prng_state *state);
extern int64 pg_prng_int64p(pg_prng_state *state);
extern uint32 pg_prng_uint32(pg_prng_state *state);
extern int32 pg_prng_int32(pg_prng_state *state);
extern int32 pg_prng_int32p(pg_prng_state *state);
extern double pg_prng_double(pg_prng_state *state);
extern bool pg_prng_bool(pg_prng_state *state);

#endif							/* PG_PRNG_H */
